package com.william.jdbcplus.core.dialects.pagination;

import com.william.jdbcplus.core.dialects.pagination.impl.*;
import com.william.jdbcplus.common.enums.DbType;
import com.william.jdbcplus.common.page.IPage;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 分页方言工厂类
 */
public class PaginationFactory {

    /**
     * 储存反射类表信息
     */
    private static final Map<DbType, IPagination> PAGE_INFO_CACHE = new ConcurrentHashMap<>();

    static {
        for (DbType dbType : DbType.values()) {
            PAGE_INFO_CACHE.put(dbType, getPaginationByDbType(dbType));
        }
    }

    public static String getPaginationSql(IPage<?> page, String buildSql, DbType dbType) {
        return getPagination(dbType).getPaginationSql(buildSql, page.offset(), page.getSize());
    }

    public static String getPaginationSql(long offset, long limit, String buildSql, DbType dbType) {
        return getPagination(dbType).getPaginationSql(buildSql, offset, limit);
    }

    private static IPagination getPagination(DbType dbType) {
        IPagination pagination = PAGE_INFO_CACHE.get(dbType);
        return pagination;
    }

    /**
     * 根据数据库类型选择不同分页方言
     *
     * @param dbType 数据库类型
     * @return 分页语句组装类
     */
    private static IPagination getPaginationByDbType(DbType dbType) {
        switch (dbType) {
            case MYSQL:
                return new MySqlPagination();
            case MARIADB:
                return new MariaDBPagination();
            case ORACLE:
                return new OraclePagination();
            case DB2:
                return new DB2Pagination();
            case H2:
                return new H2Pagination();
            case SQL_SERVER:
                return new SQLServerPagination();
            case SQL_SERVER2005:
                return new SQLServer2005Pagination();
            case POSTGRE_SQL:
                return new PostgrePagination();
            case HSQL:
                return new HSQLPagination();
            case SQLITE:
                return new SQLitePagination();
            case DM:
                return new DmPagination();
            default:
                return new OraclePagination();
        }
    }
}
